<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script>

    let  o ={
      age:1,
      name:'zhangsnag',
      cour:{
        js:70,
        java:50,
        c:10
      },
      arr:[
        {
          name:"js"
        },
        {
          name:'java'
        }, {
          name:"c"
        }
      ]
    }
    const ARRAY_METHOD=[
      'push',
      'pop',
      'shift',
      'unshft',
      'reverse',
      'srot',
      'splice'
    ]
    // 思路 原型式继承

    // arr  ==>arr.prototype ==> Object.prototype==>
    // arr  ==> 改写的方法==>arr.prototype ==> Object.prototype==>
    let array_methods = Object.create(Array.prototype);

    function ractify(o){
      let keys =Object.keys(o);
      for(let i =0;i<keys.length;i++){
        let key = keys[i];
        let value = o[key];
        // 判断属性 是不是引用类似，判断是不是数组
        // 如果是数组 就要循环数组 ，然后将数组里面的元素响应式化
        if(Array.isArray(value)){
          console.log('sss',value,value.push({name:'ss'}))
          value.__proto__ = array_methods
          for(let j=0;j<value.length;j++){
            ractify(value[j])
          }
        } else {
          // 对象或值类型
          defineReactive(o,key,value ,true)
        }
      }
    }

    ARRAY_METHOD.forEach(method =>{
      array_methods[method]=function(){
        // 调用原来的方法
      console.log('调用拦截的方法','method')

      for(let i =0 ;i<arguments.length;i++){
        ractify(arguments[i])
      }

      let res = Array.prototype[method].apply(this,arguments)
        // Array.prototype[method].call(this,...arguments)  报错 arguments不是真数组 而是类数组 扩展运算符不能这样用
        return res
      }
    })

    const defineReactive = function(target,key,value,enmuerable){
      if(typeof value ==='Object' && value !=null && !Array.isArray(value)){
        // 非数组的引用类型
      }
      Object.defineProperty(target,key,{
        configurable:true,
        enumerable:!!enmuerable,
        get(){
          console.log('a')
          return value
        },
        set(newValue){
          console.log('b')
          value = newValue
        }
      })
    }

//  到此数据已经响应式的了，但是 给对象重新赋值时 ，新的对象不是响应式的  数组赋值有bug  vue 3 采取了porxy


    ractify(o)
  </script>
</body>
</html>